#include "stream_puller_base.h"

namespace stream {

HBStreamPullerBase::HBStreamPullerBase(StreamPullerInfo* spinfo, LogInfo* log_info): 
    BasePuller(spinfo, log_info) {
}

HBStreamPullerBase::~HBStreamPullerBase() {

}

int HBStreamPullerBase::global_init() {
  int ret = 0;
  // 初始化VP
  VP_CONFIG_S struVpConf;
  memset(&struVpConf, 0x00, sizeof(VP_CONFIG_S));
  struVpConf.u32MaxPoolCnt = 32;
  HB_VP_SetConfig(&struVpConf);
  ret = HB_VP_Init();
  if (ret != 0) { spdlog::get("logger")->info("ERROR. vp_init fail ret = {}!\n", ret); }
  ret = HB_VDEC_Module_Init();
  if (ret != 0) { spdlog::get("logger")->info("ERROR. HB_VDEC_Module_Init ret = {}!\n", ret); }
  return ret;
}

int HBStreamPullerBase::global_release() {
  int ret = HB_VP_Exit();
  if (ret != 0) { spdlog::get("logger")->info("vp exit ok!"); }
  ret = HB_VDEC_Module_Uninit();
  if (ret != 0) { spdlog::get("logger")->info("ERROR. HB_VDEC_Module_Uninit ret = {}!\n", ret); }
  return ret;
}


int HBStreamPullerBase::sample_vdec_ChnAttr_init(VDEC_CHN_ATTR_S *pVdecChnAttr) {
  int streambufSize = 0;
  if (pVdecChnAttr == nullptr) {
    spdlog::get("logger")->info("pVdecChnAttr is nullptr!");
    return -1;
  }
  // 该步骤必不可少
  memset(pVdecChnAttr, 0, sizeof(VDEC_CHN_ATTR_S));
  // 设置解码模式分别为 PT_H264 PT_H265 PT_MJPEG 
  pVdecChnAttr->enType = (PAYLOAD_TYPE_E)encode_type;
  // 设置解码模式为帧模式
  pVdecChnAttr->enMode = VIDEO_MODE_FRAME;
  // 设置像素格式 NV12格式
  pVdecChnAttr->enPixelFormat = HB_PIXEL_FORMAT_NV12;
  // 输入buffer个数
  pVdecChnAttr->u32FrameBufCnt = 3;
  // 输出buffer个数
  pVdecChnAttr->u32StreamBufCnt = 3;
  // 输出buffer size，必须1024对齐
  if (puller_ifo->enType == AV_CODEC_ID_JPEG2000 || puller_ifo->enType == AV_CODEC_ID_MJPEG) {
    pVdecChnAttr->u32StreamBufSize = (puller_ifo->oriWidth * puller_ifo->oriHeight * 2 +1024) &~ 0x3ff;
  } else {
    pVdecChnAttr->u32StreamBufSize = (puller_ifo->oriWidth * puller_ifo->oriHeight * 3 / 2+1024) &~ 0x3ff;
  }

  // 使用外部buffer
  pVdecChnAttr->bExternalBitStreamBuf  = HB_TRUE;
  if (puller_ifo->enType == AV_CODEC_ID_H265) {
    // 使能带宽优化
    pVdecChnAttr->stAttrH265.bandwidth_Opt = HB_TRUE;
    // 普通解码模式，IPB帧解码
    pVdecChnAttr->stAttrH265.enDecMode = VIDEO_DEC_MODE_NORMAL;
    // 输出顺序按照播放顺序输出
    pVdecChnAttr->stAttrH265.enOutputOrder = VIDEO_OUTPUT_ORDER_DISP;
    // 不启用CLA作为BLA处理
    pVdecChnAttr->stAttrH265.cra_as_bla = HB_FALSE;
    // 配置tempral id为绝对模式
    pVdecChnAttr->stAttrH265.dec_temporal_id_mode = 0;
    // 保持2
    pVdecChnAttr->stAttrH265.target_dec_temporal_id_plus1 = 2;
  }
  if (encode_type == AV_CODEC_ID_H264) {
      // 使能带宽优化
    pVdecChnAttr->stAttrH264.bandwidth_Opt = HB_TRUE;
    // 普通解码模式，IPB帧解码
    pVdecChnAttr->stAttrH264.enDecMode = VIDEO_DEC_MODE_NORMAL;
    // 输出顺序按照播放顺序输出
    pVdecChnAttr->stAttrH264.enOutputOrder = VIDEO_OUTPUT_ORDER_DISP;
  }
  if (puller_ifo->enType == AV_CODEC_ID_MJPEG) {
    // 使用内部buffer
    pVdecChnAttr->bExternalBitStreamBuf  = HB_TRUE;
    // 配置镜像模式，不镜像
    pVdecChnAttr->stAttrJpeg.enMirrorFlip = DIRECTION_NONE;
    // 配置旋转模式，不旋转
    pVdecChnAttr->stAttrJpeg.enRotation = CODEC_ROTATION_0;
    // 配置crop，不启用
    pVdecChnAttr->stAttrJpeg.stCropCfg.bEnable = HB_FALSE;
  }
  return 0;
}

int HBStreamPullerBase::stop_pull() {
  int try_cnt = 200;
  if (stop_flag == common::CameraGrabing) {
    stop_flag = common::CameraOpened;
    while (stop_flag != common::CameraClosed && try_cnt-- > 0) {
      spdlog::get("logger")->info("HBStreamPullerBase::stop_pull stop_flag: {} ", stop_flag);
      std::this_thread::sleep_for(milliseconds(50));
    }
    if (try_cnt < 0) {exit(0);}
  }
  try_cnt = 200;
  if (stop_flag2 == common::CameraGrabing) {
    stop_flag2 = common::CameraOpened;
    while (stop_flag2 != common::CameraClosed && try_cnt-- > 0) {
      spdlog::get("logger")->info("HBStreamPullerBase::stop_pull stop_flag2: {} ", stop_flag2);
      std::this_thread::sleep_for(milliseconds(50));
    }
    if (try_cnt < 0) {exit(0);}
  }
  return 0;
}


}